using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Mogre;
using FractalSpline;
using Vector3 = Mogre.Vector3;

namespace ThirdLife.Render.MogrePlugin
{
  public class CustomShape
  {
    public ArrayList Points = null;
    protected ArrayList m_texturePoints = null;
    protected bool m_Drawn;
    private int m_count = 1;
    public global::Mogre.ManualObject MogreObj = null;
    public string MaterialName = "";
    public global::Mogre.RenderOperation.OperationTypes OperationType = global::Mogre.RenderOperation.OperationTypes.OT_TRIANGLE_LIST;

    #region constructor / destructor

    public CustomShape()
    {
      Points = new ArrayList();
      m_texturePoints = new ArrayList();
    }

    ~CustomShape()
    {
      this.Dispose();
    }

    public void Dispose()
    {

    }

    #endregion

    public void SetMaterial(string mname)
    {
      MaterialName = mname;
    }
    public void AddPoint(Vector3 p)
    {
      Points.Add(p);
    }
    public void AddTexturePoint(Vector3 p)
    {
      m_texturePoints.Add(p);
    }
    public Vector3 GetPoint(int index)
    {
      return (Vector3)Points[index];
    }

    public int GetNumPoints()
    {
      return Points.Count;
    }

    public void UpdatePoint(int index, Vector3 v)
    {
      Points[index] = v;
    }

    public void DeletePoint(int index)
    {
      Points.RemoveAt(index);
    }
    public void Clear()
    {
      Points.Clear();
      m_texturePoints.Clear();
    }

    public void InsertPoint(int index, Vector3 p)
    {
      Points.Insert(index, p);
    }

    public void DrawLine(Vector3 start, Vector3 end)
    {
      if (Points.Count > 0)
        Points.Clear();

      Points.Add(start);
      Points.Add(end);

      Draw();
    }

    public void DrawLinesList()
    {
      MogreObj = new ManualObject("tree" + m_count);
      MogreObj.Begin(this.MaterialName, global::Mogre.RenderOperation.OperationTypes.OT_LINE_LIST);
      for (int i = 0; i < this.Points.Count; i++)
      {
        MogreObj.Position((Vector3)this.Points[i]);

      }
      MogreObj.End();
      m_count++;
    }

    public void DrawLinesTriangles()
    {
      MogreObj = new ManualObject("tree" + m_count);
      MogreObj.Begin(this.MaterialName);
      for (int i = 0; i < this.Points.Count; i++)
      {
        MogreObj.Position((Vector3)this.Points[i]);
        MogreObj.TextureCoord((Vector3)this.m_texturePoints[i]);
      }
      MogreObj.End();
      m_count++;
    }

    public void DrawLinesNoTexture()
    {
      MogreObj = new ManualObject("tree" + m_count);
      MogreObj.Begin(this.MaterialName);
      for (int i = 0; i < this.Points.Count; i++)
      {
        MogreObj.Position((Vector3)this.Points[i]);
      }
      MogreObj.End();
      m_count++;
    }

    public void DrawLinesNoTextIndex()
    {
      MogreObj = new ManualObject("tree" + m_count);
      //System.Console.WriteLine("material name is " + this.MaterialName);
      MogreObj.Begin(this.MaterialName);
      for (int i = 0; i < this.Points.Count; i++)
      {
        Vector3 orig = new Vector3(30, 30, 30);
        MogreObj.Position(((Vector3)this.Points[i] - orig));
        MogreObj.TextureCoord(((Vector3)this.m_texturePoints[i]).x, ((Vector3)this.m_texturePoints[i]).y);
      }

      for (int i = 0; i < this.Points.Count; i++)
      {
        MogreObj.Index((ushort)i);
      }
      MogreObj.End();
      m_count++;
    }

    public void Draw()
    {
      // System.Console.WriteLine("drawing manual object");
      MogreObj = new ManualObject("tree" + m_count);
      MogreObj.Begin(this.MaterialName, global::Mogre.RenderOperation.OperationTypes.OT_TRIANGLE_LIST);
      for (int i = 0; i < this.Points.Count; i++)
      {
        MogreObj.Position((Vector3)this.Points[i]);

        MogreObj.TextureCoord((Vector3)this.m_texturePoints[i]);
      }

      for (int i = 0; i < this.Points.Count; i++)
      {
        MogreObj.Index((ushort)i);
      }
      MogreObj.End();
      m_count++;
    }
  }

  public class RenderToOgre : IRenderer
  {
    public CustomShape m_shape = null;
    public void AddVertex(double x, double y, double z)
    {
      m_shape.AddPoint(new Vector3((float)x, (float)y, (float)z));
    }
    public void SetNormal(double x, double y, double z)
    {
    }
    public void SetTextureCoord(double u, double v)
    {
      m_shape.AddTexturePoint(new Vector3((float)u, (float)v, 0));
    }
    public void StartTriangle()
    {
    }
    public void EndTriangle()
    {
    }
    public void SetTextureId(int iTexture)
    {
    }
    public void SetColor(double r, double g, double b)
    {
    }
  }

  public class PrimitiveWrapper
  {
    public Primitive Prim;
    public RenderToOgre Renderer;
    public CustomShape Shape;
    //public SceneNode Node;
    public string Type;
    public string Material;
    public string Name;

    public PrimitiveWrapper()
    {

    }
  }
}